package com.wt.demo;

import java.util.concurrent.*;

/**
 * @description
 * @author: wangtao
 * @date:9:52 2018/6/4
 * @email:tao8.wang@changhong.com
 */
public class ThreadPoolExecutorExtendExceptionStack {

    public static class MyTask implements Runnable {
        int a, b;

        public MyTask(int a, int b) {
            this.a = a;
            this.b = b;
        }

        public void run() {
            double re = a / b;
            System.out.println(re);
        }
    }

    public static void main(String[] args) {
        ExecutorService e = new TraceThreadPoolExecutor(0, Integer.MAX_VALUE, 0, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
        for (int i = 0; i < 5; i++) {
            e.submit(new MyTask(100, i));
        }
    }

}

class TraceThreadPoolExecutor extends ThreadPoolExecutor {

    public TraceThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    public void execute(Runnable command) {
        super.execute(wrap(command, clientStack(), Thread.currentThread().getName()));
    }

    @Override
    public Future<?> submit(Runnable task) {
        return super.submit(wrap(task, clientStack(), Thread.currentThread().getName()));
    }

    private Exception clientStack() {
        return new Exception("client trace stack");
    }

    private Runnable wrap(final Runnable task, final Exception clientStack, String clientName) {
        return () -> {
            try {
                task.run();
            } catch (Exception e) {
                clientStack.printStackTrace();
                throw e;
            }
        };
    }
}
